home *** CD-ROM | disk | FTP | other *** search
- /* net/rom level 4 (transport) protocol timer management.
- * Copyright 1989 by Daniel M. Frank, W9NK. Permission granted for
- * non-commercial distribution only.
- */
-
- #include "global.h"
- #ifdef NETROM
- #include "mbuf.h"
- #include "timer.h"
- #include "ax25.h"
- #include "netrom.h"
-
- #if !defined(_lint)
- static char rcsid[] OPTIONAL = "$Id: nr4timer.c,v 1.8 1996/08/29 12:11:16 root Exp root $";
- #endif
-
- #undef NR4DEBUG
-
- unsigned Nr_timertype = 0; /* default to binary exponential */
-
-
- /* The ACK timer has expired without any data becoming available.
- * Go ahead and send an ACK.
- */
-
- void
- nr4ackit (void *p)
- {
- struct nr4cb *cb = (struct nr4cb *) p;
- struct nr4hdr rhdr;
-
- #ifdef NR4DEBUG
- printf ("ACKIT called.\n");
- #endif
-
- stop_timer (&cb->tack); /* fixed N1BEE 920811 */
- if (cb->qfull) /* Are we choked? */
- rhdr.opcode = NR4OPACK | NR4CHOKE;
- else
- rhdr.opcode = NR4OPACK;
- rhdr.yourindex = uchar (cb->yournum);
- rhdr.yourid = uchar (cb->yourid);
- rhdr.u.ack.rxseq = cb->rxpected;
-
- nr4sframe (cb->remote.node, &rhdr, NULLBUF);
- }
-
-
- /* Called when one of the transmit timers has expired */
-
- void
- nr4txtimeout (void *p)
- {
- struct nr4cb *cb = (struct nr4cb *) p;
- unsigned seq;
- struct nr4txbuf *t;
-
- /* Sanity check */
- if (cb->state != NR4STCON)
- return;
-
- /* Scan through the send window looking for expired timers */
-
- for (seq = cb->ackxpected;
- nr4between ((unsigned) cb->ackxpected, seq, (unsigned) cb->nextosend);
- seq = (seq + 1) & NR4SEQMASK) {
-
- t = &cb->txbufs[seq % cb->window];
-
- if (t->tretry.state == TIMER_EXPIRE) {
- t->tretry.state = TIMER_STOP; /* So we don't do it again */
- /* This thing above fails because the timer code
- itself does the reverse, changing TIMER_STOP to
- TIMER_EXPIRE. What we really want to do here
- is properly restart the timer. -- N1BEE */
- /* start_timer(&(t->tretry)); */
-
- if (t->retries == Nr4retries) {
- cb->dreason = NR4RTIMEOUT;
- nr4state (cb, NR4STDISC);
- }
- t->retries++;
-
- /* We keep track of the highest retry count in the window. */
- /* If packet times out and its new retry count exceeds the */
- /* max, we update the max and bump the backoff level. This */
- /* expedient is to avoid bumping the backoff level for every */
- /* expiration, since with more than one timer we would back */
- /* off way too fast (and at a rate dependent on the window */
- /* size! */
-
- if (t->retries > cb->txmax) {
- cb->blevel++;
- cb->txmax = t->retries; /* update the max */
- }
- nr4sbuf (cb, seq); /* Resend buffer */
- }
- }
-
- }
-
-
- /* Connect/disconnect acknowledgement timeout */
-
- void
- nr4cdtimeout (void *p)
- {
- struct nr4cb *cb = (struct nr4cb *) p;
- struct nr4hdr hdr;
-
- switch (cb->state) {
- case NR4STCPEND:
- if (cb->cdtries == Nr4retries) { /* Have we tried long enough? */
- cb->dreason = NR4RTIMEOUT;
- nr4state (cb, NR4STDISC); /* Give it up */
- } else {
- /* Set up header */
-
- hdr.opcode = NR4OPCONRQ;
- hdr.u.conreq.myindex = uchar (cb->mynum);
- hdr.u.conreq.myid = uchar (cb->myid);
- hdr.u.conreq.window = uchar (Nr4window);
- memcpy (hdr.u.conreq.user, cb->local.user, AXALEN);
- memcpy (hdr.u.conreq.node, cb->local.node, AXALEN);
-
- /* Bump tries counter and backoff level, and restart timer */
- /* We use a linear or binary exponential backoff. */
-
- cb->cdtries++;
- cb->blevel++;
-
- if (Nr_timertype)
- /* linear */
- set_timer (&cb->tcd, dur_timer (&cb->tcd) + cb->srtt);
- else
- /* exponential */
- set_timer (&cb->tcd, dur_timer (&cb->tcd) * 2);
-
- start_timer (&cb->tcd);
-
- /* Send connect request packet */
-
- nr4sframe (cb->remote.node, &hdr, NULLBUF);
- }
- break;
-
- case NR4STDPEND:
- if (cb->cdtries == Nr4retries) { /* Have we tried long enough? */
- cb->dreason = NR4RTIMEOUT;
- nr4state (cb, NR4STDISC); /* Give it up */
- } else {
- /* Format header */
-
- hdr.opcode = NR4OPDISRQ;
- hdr.yourindex = uchar (cb->yournum);
- hdr.yourid = uchar (cb->yourid);
-
- /* Bump retry count and start timer */
- /* We don't really need to be fancy here, since we */
- /* should have a good idea of the round trip time by now. */
-
- cb->cdtries++;
- start_timer (&cb->tcd);
-
- /* Send disconnect request packet */
-
- nr4sframe (cb->remote.node, &hdr, NULLBUF);
- }
- break;
- default:
- break;
- }
- }
-
-
- /* The choke timer has expired. Unchoke and kick. */
-
- void
- nr4unchoke (void *p)
- {
- struct nr4cb *cb = (struct nr4cb *) p;
-
- cb->choked = 0;
- (void) nr4output (cb);
- }
-
- #endif /* NETROM */
-